package com.fs.common.utils.enhancer;

import cn.hutool.core.map.multi.RowKeyTable;
import cn.hutool.core.map.multi.Table;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

/**
 * 三元数据对象操作函数
 *
 * @author LiuQi 2025/10/24-10:57
 * @version V1.0
 **/
public class TableEnhancer<R, C, V> {
    private final Table<R, C, V> table;

    private TableEnhancer() {
        this.table = new RowKeyTable<>();
    }

    /**
     * 创建空白的增强器
     *
     * @param <R> 行类型
     * @param <C> 列类型
     * @param <V> 值类型
     * @return 增强器
     */
    public static <R, C, V> TableEnhancer<R, C, V> create() {
        return new TableEnhancer<>();
    }

    /**
     * 根据列表创建增强器
     *
     * @param list       列表对象
     * @param rowFunc    行解析函数
     * @param columnFunc 列解析函数
     * @param valueFunc  值解析函数
     * @param <R>        行类型
     * @param <C>        列类型
     * @param <V>        值类型
     * @param <S>        列表对象类型
     * @return 增强器
     */
    public static <R, C, V, S> TableEnhancer<R, C, V> from(
            List<S> list,
            Function<S, R> rowFunc,
            Function<S, C> columnFunc,
            Function<S, V> valueFunc) {
        TableEnhancer<R, C, V> enhancer = new TableEnhancer<>();
        if (CollectionUtils.isEmpty(list)) {
            return enhancer;
        }

        list.forEach(s -> enhancer.put(rowFunc.apply(s), columnFunc.apply(s), valueFunc.apply(s)));

        return enhancer;
    }

    public TableEnhancer<R, C, V> put(R r, C c, V v) {
        this.table.put(r, c, v);

        return this;
    }

    public Table<R, C, V> get() {
        return this.table;
    }

    /**
     * 创建Table采集器
     *
     * @param rowFunc    行解析函数
     * @param columnFunc 列解析函数
     * @param valueFunc  值解析函数
     * @param <T>        列表对象类型
     * @param <R>        行类型
     * @param <C>        列类型
     * @param <V>        值类型
     * @return 采集器
     */
    public static <T, R, C, V> TableCollector<T, R, C, V> collector(Function<T, R> rowFunc, Function<T, C> columnFunc, Function<T, V> valueFunc) {
        return new TableCollector<>(rowFunc, columnFunc, valueFunc);
    }

    /**
     * 创建Table采集器
     *
     * @param rowFunc    行解析函数
     * @param columnFunc 列解析函数
     * @param <T>        列表对象类型
     * @param <R>        行类型
     * @param <C>        列类型
     * @return 采集器
     */
    public static <T, R, C> TableCollector<T, R, C, T> collector(Function<T, R> rowFunc, Function<T, C> columnFunc) {
        return new TableCollector<>(rowFunc, columnFunc, s -> s);
    }

    /**
     * table采集器实现
     *
     * @param <T> 列表对象类型
     * @param <R> 行类型
     * @param <C> 列类型
     * @param <V> 值类型
     */
    public record TableCollector<T, R, C, V>(
            Function<T, R> rowFunc,
            Function<T, C> columnFunc,
            Function<T, V> valueFunc)
            implements Collector<T, Table<R, C, V>, Table<R, C, V>> {

        @Override
        public Supplier<Table<R, C, V>> supplier() {
            return RowKeyTable::new;
        }

        @Override
        public BiConsumer<Table<R, C, V>, T> accumulator() {
            return (table, t) -> table.put(rowFunc.apply(t), columnFunc.apply(t), valueFunc.apply(t));
        }

        @Override
        public BinaryOperator<Table<R, C, V>> combiner() {
            return (t1, t2) -> {
                t1.putAll(t2);
                return t1;
            };
        }

        @Override
        public Function<Table<R, C, V>, Table<R, C, V>> finisher() {
            return t -> t;
        }

        @Override
        public Set<Characteristics> characteristics() {
            return Set.of();
        }
    }
}
